import json
from flask import jsonify, Blueprint, request
from tools import log_operations, token_required, build_permission_tree
from common_tools import DateTimeEncoder
from project_model import Permission
from global_scope import get_db

db = get_db()

permission_bp = Blueprint("permission", __name__, url_prefix='/permission')


def format_permission_data(permission) -> dict:
    """
    格式化权限数据。

    :param permission: 权限对象
    :return: 格式化的权限数据字典
    """
    return {
        'id': permission.id,
        'name': permission.name,
        'code': permission.code,
        'type': permission.type,
        'parentId': permission.parentId,
        'path': permission.path,
        'redirect': permission.redirect,
        'icon': permission.icon,
        'component': permission.component,
        'layout': permission.layout,
        'keepAlive': permission.keepAlive,
        'method': permission.method,
        'description': permission.description,
        'show': permission.show,
        'enable': permission.enable,
        'order': permission.order
    }


@permission_bp.route('/menu/tree', methods=['GET'])
@log_operations
@token_required
def get_menu_permissions_tree():
    """
    获取菜单权限树。

    :return: 菜单权限树的JSON响应
    """
    permissions = Permission.query.filter_by(type="MENU").all()
    menu_permissions_tree = build_permission_tree(permissions)

    response_data = {
        'code': 0,
        'message': 'OK',
        'data': menu_permissions_tree,
        'originUrl': '/permission/menu/tree'
    }
    return jsonify(response_data), 200


@permission_bp.route('/tree', methods=['GET'])
@log_operations
@token_required
def get_all_permissions_tree():
    """
    获取所有权限树。

    :return: 所有权限树的JSON响应
    """
    permissions = Permission.query.all()
    permissions_tree = build_permission_tree(permissions)

    response_data = {
        'code': 0,
        'message': 'OK',
        'data': permissions_tree,
        'originUrl': '/permission/tree'
    }
    return jsonify(response_data), 200


@permission_bp.route('/<int:permission_id>', methods=['DELETE'])
@log_operations
@token_required
def delete_permission(permission_id):
    """
    删除权限。

    :param permission_id: 权限ID
    :return: 删除权限的JSON响应
    """
    permission = db.session.get(Permission, permission_id)
    if not permission:
        return jsonify({'code': 1, 'message': 'Permission not found'}), 404

    db.session.delete(permission)
    db.session.commit()

    response_data = {
        'code': 0,
        'message': 'Permission deleted successfully',
        'data': {},
        'originUrl': f'/permission/{permission_id}'
    }
    return jsonify(response_data), 200


@permission_bp.route('', methods=['POST'])
@log_operations
@token_required
def add_permission():
    """
    新增权限。

    :return: 新增权限的JSON响应
    """
    data = request.get_json()
    required_fields = ['name', 'code', 'type']

    for field in required_fields:
        if field not in data:
            return jsonify({'code': 1, 'message': f'Missing required field: {field}'}), 400

    new_permission = Permission(
        name=data['name'],
        code=data['code'],
        type=data['type'],
        parentId=data.get('parentId'),
        path=data.get('path', ''),
        redirect=data.get('redirect'),
        icon=data.get('icon'),
        component=data.get('component'),
        layout=data.get('layout'),
        keepAlive=data.get('keepAlive'),
        method=data.get('method'),
        description=data.get('description'),
        show=data.get('show', 1),
        enable=data.get('enable', 1),
        order=data.get('order')
    )

    db.session.add(new_permission)
    db.session.commit()

    response_data = {
        'code': 0,
        'message': 'Permission added successfully',
        'data': format_permission_data(new_permission),
        'originUrl': '/permission'
    }

    return jsonify(response_data), 201


@permission_bp.route('/<int:permission_id>', methods=['PATCH'])
@log_operations
@token_required
def update_permission(permission_id):
    """
    修改权限。

    :param permission_id: 权限ID
    :return: 修改权限的JSON响应
    """
    data = request.get_json()
    permission = db.session.get(Permission, permission_id)
    if not permission:
        return jsonify({'code': 1, 'message': 'Permission not found'}), 404

    permission.name = data.get('name', permission.name)
    permission.code = data.get('code', permission.code)
    permission.type = data.get('type', permission.type)
    permission.parentId = data.get('parentId', permission.parentId)
    permission.path = data.get('path', permission.path)
    permission.redirect = data.get('redirect', permission.redirect)
    permission.icon = data.get('icon', permission.icon)
    permission.component = data.get('component', permission.component)
    permission.layout = data.get('layout', permission.layout)
    permission.keepAlive = data.get('keepAlive', permission.keepAlive)
    permission.method = data.get('method', permission.method)
    permission.description = data.get('description', permission.description)
    permission.show = data.get('show', permission.show)
    permission.enable = data.get('enable', permission.enable)
    permission.order = data.get('order', permission.order)

    db.session.commit()

    response_data = {
        'code': 0,
        'message': 'Permission updated successfully',
        'data': format_permission_data(permission),
        'originUrl': f'/permission/{permission_id}'
    }

    return jsonify(response_data), 200


@permission_bp.route('/button/<int:permission_id>', methods=['GET'])
@log_operations
@token_required
def get_buttons(permission_id):
    buttons = Permission.query.filter_by(parentId=permission_id, type='BUTTON').all()
    button_list = [
        {
            'id': button.id,
            'name': button.name,
            'code': button.code,
            'type': button.type,
            'parentId': button.parentId,
            'path': button.path,
            'redirect': button.redirect,
            'icon': button.icon,
            'component': button.component,
            'layout': button.layout,
            'keepAlive': button.keepAlive,
            'method': button.method,
            'description': button.description,
            'show': button.show,
            'enable': button.enable,
            'order': button.order
        } for button in buttons
    ]

    response_data = {
        'code': 0,
        'message': 'OK',
        'data': button_list,
        'originUrl': f'/permission/button/{permission_id}'
    }

    response = json.dumps(response_data, cls=DateTimeEncoder, ensure_ascii=False)
    return jsonify(json.loads(response)), 200
